/* ======================================================================================== *\

		FILE:				Pipe.cpp
		AUTHOR:				Jack Hoxley

		DESCRIPTION:		One or more pipes will grow until the layout is exhausted, the
							class implemented in this file encapsulates the simulation of a
							single pipe.

		CHANGE:				6th May 2007
								Stubs for public ctor/dtor implemented.
							8th May 2007
								Filled in stubs with basic CoordinateList and PRNG impl
							14th July 2007
								Implemented 'RollBackLastMove()' and 'SetLastUpdated()'

\* ======================================================================================== */

// Include Standard Headers
// ------------------------
#include "DXUT.h"

#pragma warning( disable : 4995 ) // Not interested in deprectation warnings
#include <sstream>
#pragma warning( default : 4995 )

#include <algorithm>

// Include project headers
// -----------------------
#include "Utils.h"
#include "Profiling.h"
#include "Pipe.h"



namespace PipeSim
{
	// ===========================
	// P U B L I C   M E M B E R S
	// ===========================

	Pipe::Pipe( const Utils::IntegerVector start )
	{
		ENTER;

		m_LastUpdated = 0;

		path.push_back( start );
	}



	Pipe::Pipe( const UINT16& startX, const UINT16& startY, const UINT16& startZ )
	{
		ENTER;

		m_LastUpdated = 0;

		path.push_back( Utils::IntegerVector( startX, startY, startZ ) );
	}



	Pipe::~Pipe()
	{
		ENTER;
	}



	UINT16 Pipe::ChooseNextMove( const Utils::CoordinateList moves )
	{
		ENTER;

		// Choose one of the possible moves
		UINT16 i = static_cast< UINT16 >( Utils::RndInRange( 0, static_cast< int >( moves.size() ) ) );

		path.push_back( moves.at( i ) );

#ifdef DEBUG
		PrintPath( );
#endif

		return i;
	}



	void Pipe::RollBackLastMove( )
	{
	}



	void Pipe::SetLastUpdated( const UINT32& v )
	{
		m_LastUpdated = v;
	}



	UINT32 Pipe::LastUpdated( )
	{
		return m_LastUpdated;
	}



	Utils::IntegerVector Pipe::Head()
	{
		return path.back();
	}


	void Pipe::CopyCurrentCoordinateList( Utils::CoordinateList* list )
	{
		std::copy( path.begin(), path.end(), list->begin() );
	}



	UINT32 Pipe::GetPipeLength( )
	{
		return static_cast< UINT32 >( path.size() );
	}



	// =============================
	// P R I V A T E   M E M B E R S
	// =============================
	void Pipe::PrintPath( )
	{
		Utils::CoordinateList::iterator it;

		std::wostringstream woss;
		woss << L"Path of " << path.size() << L" steps is ";

		for( it = path.begin(); it != path.end(); ++it )
		{
			woss << L"<" << (*it).x << L"," << (*it).y << L"," << (*it).z << L">,";
		}

		Utils::OutputMessage( Utils::Information, L"PrintPath", __LINE__, woss.str().c_str() );
	}
};